<?
/* / / / / / ENGINE  CORE / / / / / / /
|	          CORE CLASS              |
|       (aka. CMS superclass)         |
|                                     |
| version:     0.2.0                  |
| last edit:   20100131               |
| package:     beta 2                 |
/ / / / / / / / / / / / / / / / / / /*/


class ENGINE {
	
	const public_dir		= "www";
	const cp_dir			= "subdomains";
	const session_init		= "init";
	const session_sitemap	= "map";
	
	
	function __construct() {
	
		// BUILDING IMPLEMENTED CLASSES
		$this->text = new ENGINE_TEXT();
	}

	function _addvars( $vars ){ 
		
		foreach($vars as $k=>$v) $this->$k = $v;
	}
	
	function get( $what ) {
		global $DB;
		
		if( !$_SESSION['init'][ $what ] )
			$_SESSION['init'][ $what ] = $DB->query_direct ( "select value from settings where `key`='$what' && active" );

		return $_SESSION['init'][$what];
	}
	
	/*function include_class( ) {
		foreach( func_get_args() as $what ) include_once( ENGINE_CORE . "class/" . $what );
	}*/
	
	
/** 	USER FUNCS
* User conditionals, data get/push and session control
* Should be in extended class in the future */
	function user_get( $what, $meta=false) {
		return ($var = $this->user[ $what ])? $var : $this->user_extend( $what );
	}
	
	function user_extend( $what ) {
		global $DB;
		
		if( !empty($_SESSION['uid']) && !$this->user[ $what ]) {
			if ( empty( $this->user )) {
				$this->user = $DB->get( 'user', 'ID = ' . $_SESSION['uid'] );
			}
			$this->user = array_merge( $this->user, json_decode( $this->user['meta'], true ));
		}
		
		return $this->user[ $what ];
	}

	function user_session( $private = 0 ) {
		global $DB;
		if( isset($_SESSION['uid']) ){
			$this->user = $DB->get("user", "ID=" . $DB->smartq( $_SESSION['uid'] ) . (( $private )?
				" && (ip='".gethostbyname( $_SERVER['REMOTE_ADDR'] )."' || multiple=1) && date_add(llog,interval timer minute) > now()" : "") );
		} else $this->user = false;
		
		if( $private ) $this->user_session_private();
	}
	
	function user_session_private() {
		global $Page;
		
		if( $this->user && $this->user_get('rank') >= $Page->get('private') ) {
			
			mysql_query("UPDATE user SET llog=NOW() WHERE ID='". $this->user_get('ID') ."'");
			
		} else header("Location: ". (( $red = $Page->get( 'public' ))? $red : engine_get('url')));
	}
	
	
	function user_authenticate( $user, $password, $rank = 7 ) {
		
		global $DB;
		if( $this->user = $DB->get( 'user', "user=". $DB->smartq( $user ) ." AND rank>=$rank AND pass=". $DB->smartq( $password ) )) {
			
			$_SESSION['uid'] = $this->user[ 'ID' ];
			$DB->query( "UPDATE user SET ip='".gethostbyname($_SERVER['REMOTE_ADDR'])."', llog=NOW() WHERE ID=". $this->user_get('ID') );
			$DB->query( "UPDATE mod_user SET tlog=tlog+1 WHERE ID=". $this->user_get('ID') );
				return true;
		} else	return false;
	}

	
/**		BOOLEAN & RETURNING CHECKS
* Important: *only* functions usable in all fronts!
*							*/

	function type_exists() {
		global $DB;
		
		foreach( func_get_args() as $type )
			if( $DB->type( $type )) return $type;
	}

	
/**		OUTPUT FUNCTIONS
* Important: *only* functions usable on all fronts!
*							*/
	
	function page_by_ID( $id ) {
		global $DB;
		foreach( $_SESSION['map']['menu'] as $node ) if($id == (int) $node['ID']) $page = $node; 
		if( !$page && !$page = $_SESSION['map']['dump'][$id] )
			$page = $_SESSION['map']['dump'][$id] = $DB->get( "page", "ID=$id", "*, <%lang:pages.nameid%> as title, (SELECT GROUP_CONCAT(ID) FROM pages AS sp WHERE sp.parent = pages.ID ORDER BY sp.hierarchy ASC) AS sub" );

		return $page;
	}
	
		
	
/**		INPUT FUNCTIONS
* Superclass input functions should only be here incase usable for both frontend/backend
* Since ROOM can access these, _smartq should always be used!
* Some functions will be overwritten by subclasses	*/
	function set( $key, $value ) {
		global $DB;

		$ref = ( $DB->query_direct( "select 1 from settings where `key`='$key'" ))? "update settings set `value`='$value' where ID=$ref" : "insert into `settings` (`key`, `value`, `active`, `llog`) values ('$key', '$value', 1, now())";
		$DB->query( $ref , 0 );

		return $value;
	}
	
	function set_for_session( $what, $value) {
		$_SESSION['init'][ $what ] = $value;
	}
	
	function insert_text($string, $field = 'short', $lang = LANG) {
		global $DB;
		$DB->tube("insert into txtdump(textid, active, lang, `$field`) select max(textid)+1, 1, '$lang', ".$DB->_smartq($string)." from txtdump" );
		return $DB->short("MAX(textid)", "txtdump", "active=1");
	}
	
	function camelize($string) {
		foreach ( explode(".", $string) as $part ) $return[] = ucfirst($part); 
		return implode("", $return);
	}
	
	function insert_module( $array ) {
		global $DB;
		if( is_string( $array ) ) $array = json_decode( $array, true );
		$DB->tube("insert into moddump(json, llog, author) values ('".json_encode($array)."', now(), ".$this->user_get('ID').")");
		return $DB->short( "ID", "moddump", "json like '%" . $array['mod'] . "%' order by ID desc" );
	}
}


/** 	TEXT FUNCS
* Get text and conditionals (no set!)
* 											 */

class ENGINE_TEXT {
		function __construct() {
			
		}
		
		public function filter( $textid, $column = "short" ) {
			global $DB;
			
			$response = $DB->query( "select distinct lang, `$column` from txtdump where textid=$textid && active" );
			if( $response )
				while( $row = mysql_fetch_array( $response, MYSQL_ASSOC)) $result[ $row[ 'lang' ]] = $row[ $column ];
		
			return $result;
		}
		
		
		public function get( $textid, $column = "short", $lang = LANG, $strict = false ) {
			global $DB;
			
			 $select = ( $strict || engine_get('lang.master') == $lang ) ?
				 "='$lang'" : "IN('$lang','". engine_get('lang.master') ."') ORDER BY lang ".(($lang > engine_get('lang.master'))? "DESC":"");
		
			return utf8_encode( $DB->query_direct( "select `$column` from txtdump where textid = $textid && lang $select limit 1" ));
		}
						
		public function reference( $objtype, $objid, $column = "short", $objcolumn = "nameid" ) {
			global $DB;
			
			if( $objcolumn == "nameid" && $column == "long" ) $objcolumn = "textid";
			
			return $DB->get_key( $objtype, "ID = $objid", "<%lang:$objcolumn:$column%>" );
		}
		
		
		public function search( $string, $column = "short", $lang = LANG ) {
			global $DB;
			
			$response = $DB->query( "select textid, $column from txtdump where $column like '%".$DB->smartq( $string )."%' && lang='$lang'" );
			while( $row[] = mysql_fetch_array( $response, MYSQL_ASSOC));
		
			return $row;
		}
	
}




/** 	USER FUNCS
* User conditionals, data get/push and session control
*													*/

class ENGINE_USER {

		
	public function get( $what, $meta=false) {
		
		return ($var = $this->user[ $what ])? $var : $this->extend( $what );
	}
	
	private function extend( $what ) {
		global $DB;
		
		if( $this->id && !$this->user[ $what ])
			$this->user = array_merge( $this->user, json_decode( $this->user['meta'], true ));
		
		return $this->user[ $what ];
	}
	
	public function session( $private = 0 ) {
		global $DB;
		if( isset($_SESSION['uid']) ){
			$this->user = $DB->get("user", "ID=" . $DB->smartq( $_SESSION['uid'] ) . (( $private )?
				" && (ip='".gethostbyname( $_SERVER['REMOTE_ADDR'] )."' || multiple=1) && date_add(llog,interval timer minute) > now()" : "") );
			
				$this->id = (int) $_SESSION['uid'];
		} else	$this->id = false;
		
		if( $private ) $this->session_private();
	}
	
	public function session_private() {
		global $Page;
		
		if( $this->id && $this->get('rank') >= $Page->get('private') ) {
			
			mysql_query("UPDATE user SET llog=NOW() WHERE ID='". $this->id ."'");
			
		} else header("Location: ".engine_get('url'));
	}
	
	function set( $user_or_id, $values = false ) {
		global $DB;
		
		if( !$values->rank ) $values->rank = 1;	 
		if( !is_int( $user_or_id )) $values->user = $DB->simplestring( $user_or_id );
		
		if( !$User = $DB->get_object ( "user", is_int( $user_or_id )? $user_or_id : "user=" . $DB->smartq( $user_or_id )))
			 $User = new OBJECT( "user", 0, true, $values );
		
		else foreach(  $values as $key => $value ) $User->set( isset( $User->values[ $key ] )? $key : "meta.$key", $value );
		
		return $User->id;
	}
		
	function authenticate( $user, $password, $rank = 7 ) {
		
		global $DB;
		if( $this->user = $DB->get( 'user', "user=". $DB->smartq( $user ) ." AND rank>=$rank AND pass=". $DB->smartq( $password ) )) {
			
			$_SESSION['uid'] = $this->user[ 'ID' ];
			$DB->query( "UPDATE user SET ip='".gethostbyname($_SERVER['REMOTE_ADDR'])."', llog=NOW() WHERE ID=". $this->user_get('ID') );

				return true;
		} else	return false;
	}
	

}

?>